/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
         http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */

#include "common/lang/comparator.h"
#include "common/log/log.h"
#include "common/type/vector_type.h"
#include "common/type/attr_type.h"
#include "common/type/data_type.h"
#include "common/value.h"
#include "sql/expr/expression.h"
#include <cmath>
#include <cstdint>
#include <regex>
#include <string>
#include <vector>


vector<float> get_vector_from_char(const string &data);


RC VectorType::add(const Value &left, const Value &right, Value &result) const
{
  //默认左边一定这是当前类型
  ASSERT(left.attr_type() == AttrType::VECTORS, "invalid type");
  ASSERT(right.attr_type() == AttrType::VECTORS || right.attr_type() == AttrType::CHARS, "invalid type");

  //考虑将string转化为vector
  int left_len = 0, right_len = 0;
  float *left_vector_value = left.get_vector(left_len);
  float *right_vector_value = right.get_vector(right_len);
  if (left_vector_value == nullptr || right_vector_value == nullptr) {
    LOG_WARN("this value=%s cannot compare to vector ", &right);
    return RC::INVALID_ARGUMENT;
  }

  //这个获取长度有问题
  if (left_len != right_len) {
    LOG_WARN("this value=%s can compare to vector, but the has different lens", &right);
    return RC::INVALID_ARGUMENT;
  }

  vector<float> numbers;
  //比较
  for (int i = 0; i < left_len/sizeof(float); i++) {
    numbers.emplace_back(left_vector_value[i] + right_vector_value[i]);
  }

  result.set_vector(numbers);
  vector<float>().swap(numbers);
  return RC::SUCCESS;
}
RC VectorType::subtract(const Value &left, const Value &right, Value &result) const
{
      //默认左边一定这是当前类型
  ASSERT(left.attr_type() == AttrType::VECTORS, "invalid type");
  ASSERT(right.attr_type() == AttrType::VECTORS || right.attr_type() == AttrType::CHARS, "invalid type");

  //考虑将string转化为vector
  int left_len = 0, right_len = 0;
  float *left_vector_value = left.get_vector(left_len);
  float *right_vector_value = right.get_vector(right_len);
  if (left_vector_value == nullptr || right_vector_value == nullptr) {
    LOG_WARN("this value=%s cannot compare to vector ", &right);
    return RC::INVALID_ARGUMENT;
  }

  //这个获取长度有问题
  if (left_len != right_len) {
    LOG_WARN("this value=%s can compare to vector, but the has different lens", &right);
    return RC::INVALID_ARGUMENT;
  }

  vector<float> numbers;
  //比较
  for (int i = 0; i < left_len/sizeof(float); i++) {
    numbers.emplace_back(left_vector_value[i] - right_vector_value[i]);
  }
  result.set_vector(numbers);
  return RC::SUCCESS;
}
RC VectorType::multiply(const Value &left, const Value &right, Value &result) const
{
      //默认左边一定这是当前类型
  ASSERT(left.attr_type() == AttrType::VECTORS, "invalid type");
  ASSERT(right.attr_type() == AttrType::VECTORS || right.attr_type() == AttrType::CHARS, "invalid type");

  //考虑将string转化为vector
  int left_len = 0, right_len = 0;
  float *left_vector_value = left.get_vector(left_len);
  float *right_vector_value = right.get_vector(right_len);
  if (left_vector_value == nullptr || right_vector_value == nullptr) {
    LOG_WARN("this value=%s cannot compare to vector ", &right);
    return RC::INVALID_ARGUMENT;
  }

  //这个获取长度有问题
  if (left_len != right_len) {
    LOG_WARN("this value=%s can compare to vector, but the has different lens", &right);
    return RC::INVALID_ARGUMENT;
  }

  vector<float> numbers;
  //比较
  for (int i = 0; i < left_len/sizeof(float); i++) {
    numbers.emplace_back(left_vector_value[i] * right_vector_value[i]);
  }

  result.set_vector(numbers);
  vector<float>().swap(numbers);
  return RC::SUCCESS;
}

int VectorType::compare(const Value &left, const Value &right) const
{
  //默认左边一定这是当前类型
  ASSERT(left.attr_type() == AttrType::VECTORS, "invalid type");
  ASSERT(right.attr_type() == AttrType::VECTORS || right.attr_type() == AttrType::CHARS, "invalid type");

  //考虑将string转化为vector
  int left_len = 0, right_len = 0;
  float *left_vector_value = left.get_vector(left_len);
  float *right_vector_value = right.get_vector(right_len);
  if (left_vector_value == nullptr || right_vector_value == nullptr) {
    LOG_WARN("this value=%s cannot compare to vector ", &right);
    return -2;
  }

  //这个获取长度有问题
  if (left_len != right_len) {
    LOG_WARN("this value=%s can compare to vector, but the has different lens", &right);
    return -2;
  }

  //比较
  int result = 0;
  for (int i = 0; i <left_len; i++) {
    result = common::compare_float(&left_vector_value[i], &right_vector_value[i]);
    if (result != 0) {
      break;
    }
  }
  return result;
} 

RC VectorType::set_value_from_str(Value &val, const string &data) const
{
  //如何将
  //首先判断是否符合
  //符合后将其转换为float类型
  auto isValidVectorString = [](const std::string &vectorStr) {
    // 正则表达式用于匹配向量格式，例如 "[1.1,-1.2]"
    std::regex pattern(R"(\[\s*-?\d+(\.\d+)?\s*(,\s*-?\d+(\.\d+)?\s*)*\])");
    return std::regex_match(vectorStr, pattern);
  };

  if (!isValidVectorString(data)) {
    return RC::INVALID_ARGUMENT;
  }

  vector<float> numbers = get_vector_from_char(data);
  val.set_vector(numbers); 
  vector<float>().swap(numbers);
  return RC::SUCCESS;
}

RC VectorType::cast_to(const Value &val, AttrType type, Value &result) const
{
  switch (type) {
    case AttrType::CHARS:{
      result.set_type(type);
      std::string s;
      to_string(val, s);
      result.set_string(s.c_str());
      return RC::SUCCESS;
    }break;
    default: return RC::UNIMPLEMENTED;
  }
}

int VectorType::cast_cost(AttrType type)
{
  if (type == AttrType::VECTORS) {
    return 0;
  }else {
    return 2;
  }
  return INT32_MAX;
}

RC VectorType::to_string(const Value &val, string &result) const
{
  ostringstream ss;
  //重新构造
  int len = val.length()/sizeof(float);
  ss << '[';
  for(int i = 0; i < len; i++ )
  {
    if (i != len - 1) {
      ss << std::round(val.value_.vector_value_[i] * 100) / 100.0 <<',';
    }else {
      ss << std::round(val.value_.vector_value_[i] * 100) / 100.0;
    }
  }

  ss << ']';
  result = ss.str();
  return RC::SUCCESS;
}

vector<float> get_vector_from_char(const string &data){
  vector<float> numbers;  
  std::string       cleanedStr = data.substr(1, data.length() - 2);  // 去掉两端的方括号
  std::stringstream ss(cleanedStr);

  std::string item;
  while (std::getline(ss, item, ',')) {  // 以逗号为分隔符读取
    numbers.push_back(std::stof(item));  // 转换为 float 并加入到结果向量
  }
  return numbers;
}


RC VectorType::count_vector_distance(const Value &left, const Value &right, Value &result, VectorFunctionExpr::Type type) const
{

  ASSERT(left.attr_type() == AttrType::VECTORS || left.attr_type() == AttrType::CHARS, "invalid type");
  ASSERT(right.attr_type() == AttrType::VECTORS || right.attr_type() == AttrType::CHARS, "invalid type");

  int left_len = 0, right_len = 0;
  float *left_vector_value = left.get_vector(left_len);
  float *right_vector_value = right.get_vector(right_len);
  if (left_vector_value == nullptr || right_vector_value == nullptr) {
    LOG_WARN("this value=%s cannot compare to vector ", &right);
    return RC::INVALID_ARGUMENT;
  }
  //这个获取长度有问题
  if (left_len != right_len) {
    LOG_WARN("this value=%s can compare to vector, but the has different lens", &right);
    return RC::INVALID_ARGUMENT;
  }
  float res = 0;
  //根据名称做计算
  if (type == VectorFunctionExpr::Type::L2_DISTANCE) {
    float tmp = 0;
    for (int i = 0; i < left_len; i++) { 
      tmp += pow((left_vector_value[i] - right_vector_value[i]), 2);
    }
    res = std::sqrt(tmp);
  }else if (type == VectorFunctionExpr::Type::CONSINE_DISTANCE) {
    float tmp_xy = 0, tmp_x = 0, tmp_y = 0;
    for (int i = 0; i < left_len; i++) { 
      tmp_xy += left_vector_value[i] *right_vector_value[i];
      tmp_x += pow(left_vector_value[i], 2);
      tmp_y += pow(right_vector_value[i], 2);
    }
    res = std::sqrt(tmp_xy/(sqrt(tmp_x) * sqrt(tmp_y)));
  }else if (type == VectorFunctionExpr::Type::INNER_PRODUCT) {
    float tmp = 0;
    for (int i = 0; i < left_len; i++) { 
      tmp += left_vector_value[i] *right_vector_value[i];
    }
    res = tmp;
  }
  //比较
  for (int i = 0; i < left_len; i++) {
    //numbers.emplace_back(left_vector_value[i] + right_vector_value[i]);
  }

  result.set_float(res);
  return RC::SUCCESS;
}